<?php
  /**
   * Provides helper functions to work with XML files
   *
   * @author Macdonald Terrence Robinson
   * @package Core
   *
   */
  final class XML
  {
    public static function load($urlOrFilePathToXML, $parseBeforeReturn=false)
    {
      $data = FileSystem::readFile($urlOrFilePathToXML, $parseBeforeReturn);
      $xmlObject = self::loadString($data);
      return $xmlObject;
    }
    
    public static function loadString($xmlData)
    {
      $xmlObject = simplexml_load_string($xmlData);
      return $xmlObject;
    }

    public static function getNodeByAttributes($simpleXMLObject, array $whereAttributes, $xpathLevel = '//*')
    {
      $whereString = '';
      $index = 0;
      $arraySize = count($whereAttributes);

      foreach ($whereAttributes as $key=>$value)
      {
        $whereString = $whereString.'@'.strtolower($key).'="'.strtolower($value).'"';

        if($index < $arraySize-1)
          $whereString = $whereString.' and ';
          
        $index++;
      }
      
      $xpath = $xpathLevel.'['.$whereString.']';

      $currentNode = self::getNodesByXPath($simpleXMLObject, $xpath);

      return $currentNode;
    }
    
    public static function getNodesByXPath($simpleXMLObject, $XPathQuery)
    {
      return $simpleXMLObject->xpath($XPathQuery);
    }

    public static function delete(SimpleXMLElement $simpleXMLObject)
    {
      $node = dom_import_simplexml($simpleXMLObject);
      $parentNode = $node->parentNode;

      $parentNode->removeChild($node);
      return true;
    }
    
    public static function deleteChildsNodes(SimpleXMLElement $parentNode, $childTagNameToDelete)
    {
      while( count($parentNode->children()) > 0)
        self::delete( $parentNode->children()->$childTagNameToDelete );
      
      return $parentNode;
    }
    
    public static function addNode(SimpleXMLElement $parentNode, $nodeName, $nodeValue = '',  $attributesKeyValueArray = array() )
    {
      $childNode = $parentNode->addChild($nodeName, $nodeValue);

      foreach ($attributesKeyValueArray as $key=>$value)
        $childNode->addAttribute((string)$key, (string)$value);

      return $childNode;
    }

    public static function addChildNode(SimpleXMLElement $parentNode, SimpleXMLElement $node)
    {
      $childNode = $parentNode->addChild( $node->getName() );

      foreach($node->attributes() as $key=>$value)
        $childNode->addAttribute($key, $value);

      foreach($node->children() as $subChildNode)
        self::addChildNode($childNode, $subChildNode);

      return $childNode;
    }

    public static function save(SimpleXMLElement $xmlObject, $savePath, $parseBeforeSaving, $permissions=0755)
    {
      if( $xmlObject == NULL )
        return false;

      $doc = new DOMDocument('1.0');

      $doc->preserveWhiteSpace = false;

      $xmlString = str_replace(array('&nbsp'), array('&#160'), $xmlObject->asXML());

      if(!$doc->loadXML( $xmlString ))
        return false;
        
      $doc->formatOutput = true;

      $data = $doc->saveXML();
      
      $data = stripslashes($data);
      
      FileSystem::saveData($savePath, $data, $parseBeforeSaving);
      
      return true;
    }
    
  }
?>
